﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Rhino.Mocks;
using SimpleServiceBus.Bus;
using SimpleServiceBus.Bus.Pipeline;
using SimpleServiceBus.Bus.Pipeline.PipelineComponents.MessageFiltering;
using SimpleServiceBus.Bus.Pipeline.PipelineComponents.MessageLogging;
using SimpleServiceBus.Endpoint;
using SimpleServiceBus.Endpoint.Metadata;

namespace SimpleServiceBus.Tests.Bus.Pipeline.PipelineComponents.MessageFiltering
{
    [TestFixture]
    public class MessageFilterComponentTestFixture
    {
        [Test]
        public void ComponentShouldFetchFilterServiceAndAttemptToMatchMessage()
        {
            //Given
            var message = new MessageEnvelope();

            var pipeline = MockRepository.GenerateStub<IMessagePipeline>();
            pipeline.Stub(p => p.PipelineDirection).Return(PipelineDirection.Receive);

            var ctx = MockRepository.GenerateMock<IMessageContext>();
            ctx.Stub(c => c.MessagePipeline).Return(pipeline);
            pipeline.Stub(p => p.CurrentContext).Return(ctx);

            var filterService = MockRepository.GenerateStub<IMessageFilterService>();
            filterService.Stub(fs => fs.Matches(message, PipelineDirection.Receive)).Return(true);
            ctx.Stub(c => c.GetLocalService<IMessageFilterService>()).Return(filterService);

            //When
            var component = new MessageFilterComponent { Pipeline = pipeline };
            component.ProcessMessage(message);

            //Then
            filterService.AssertWasCalled(s => s.Matches(message, PipelineDirection.Receive));
        }

        [Test]
        public void ComponentShouldAbortProcessingWhenFilterReturnsFalse()
        {
            //Given
            var message = new MessageEnvelope();

            var pipeline = MockRepository.GenerateStub<IMessagePipeline>();
            pipeline.Stub(p => p.PipelineDirection).Return(PipelineDirection.Receive);

            var ctx = MockRepository.GenerateMock<IMessageContext>();
            ctx.Stub(c => c.MessagePipeline).Return(pipeline);
            pipeline.Stub(p => p.CurrentContext).Return(ctx);

            var filterService = MockRepository.GenerateStub<IMessageFilterService>();
            filterService.Stub(fs => fs.Matches(message, PipelineDirection.Receive)).Return(false);
            ctx.Stub(c => c.GetLocalService<IMessageFilterService>()).Return(filterService);
            //When
            var component = new MessageFilterComponent { Pipeline = pipeline };
            component.ProcessMessage(message);

            //Then
            filterService.AssertWasCalled(s => s.Matches(message, PipelineDirection.Receive));
            ctx.AssertWasCalled(c => c.AbortMessageProcessing = true);
        }
    }
}
